package lib.grav;

import java.awt.Point;

import lib.Universe;
import lib.player.Player;

//not static! because every client thread needs its own ForceHandler.

public class ForceHandler extends Thread {
	private boolean finished = false;
	Player player = null;
	private static final double BLACKHOLE_RADIUS = 10;
	public double time = 50f/1000; //0.02
	public double BlackxPos = 500, BlackyPos = 500;
	public double BlackxForce, BlackyForce;
	public double xPos, yPos;
	public double xForce = 0, yForce = 0;
	public int BlackMass = 5; //1000
	private float maxSpeed = 2;


	public boolean inBlackHole = false;

	public Universe parent;

	public ForceHandler(Universe parent, Point blackPos, Player pl) {
		this.parent=parent;
		while(blackPos==null){
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		BlackxPos = blackPos.getX();
		BlackyPos = blackPos.getY();
		this.player = pl;
		xPos=pl.xPos;
		yPos=pl.yPos;
		/*
		 * this.parent = u; this.playerID = index;
		 */
	}

	public void vectorUpdate(double xForceAdd, double yForceAdd) {
		double x = xForce + xForceAdd * time;
		double y = yForce + yForceAdd * time;
		if (Math.abs(x) <= maxSpeed)
			xForce = x;
		if (Math.abs(y) <= maxSpeed)
			yForce = y;
	}

	/**
	 * speed as force vector
	 */

	public void  move() {
		if (Math.abs(xForce) > maxSpeed)
			xForce = maxSpeed * getPrefix(xForce);
		if (Math.abs(yForce) > maxSpeed)
			yForce = maxSpeed * getPrefix(yForce);
		xPos = player.xPos + xForce;
		yPos = player.yPos + yForce;
	}

	/**
	 * physically correct Force divided by mass is acceleration multiplicated
	 * with time is speed
	 */

	public void speedup(int MyMass) {
		xForce = xForce + xForce / MyMass ;
		yForce = yForce + yForce / MyMass;

	}

	public int work(int PLAYER_MASS) {
		attraction(PLAYER_MASS);
		deflection();
		speedup(PLAYER_MASS);
		if (!finished && Math.abs(BlackxPos - xPos) < BLACKHOLE_RADIUS
				&& Math.abs(BlackyPos - yPos) < BLACKHOLE_RADIUS) {
			if (player.ITEM.win) {
				finished = true; 
				return 1;
			} else {
				BlackMass = BlackMass + 999;
				inBlackHole = true;
				finished = true;
				return 0;
			}
		}
		return -1;
	}

	/**
	 * calculates the effective attraction from the Black Hole as a vector
	 * Proportions are proportional towards distance (BlackPos - Pos) but Length
	 * depends on Gravitation (F = Gm1m2/r^2)
	 */

	public void attraction(int MyMass) {
		double bvector1length = Math.sqrt(Math.pow(BlackxPos - xPos, 2)
				+ Math.pow(BlackyPos - yPos, 2));
		double bvector2length = BlackMass * MyMass
				/ Math.pow(bvector1length, 2);
		BlackxForce = (BlackxPos - xPos) * bvector2length;
		BlackyForce = (BlackyPos - yPos) * bvector2length;
	}

	/**
	 * calculates the deflection caused by the Black Hole: speed vector +
	 * attraction vector = new speed vector
	 */

	public void deflection() {
		double vector1length = Math.sqrt(xForce * xForce + yForce * yForce);
		xForce = xForce + BlackxForce;
		yForce = yForce + BlackyForce;
		double vector2length = Math.sqrt(xForce * xForce + yForce * yForce);
		if (vector1length != 0) {
			xForce = xForce * (vector1length / vector2length);
			yForce = yForce * (vector1length / vector2length);
		}
	}



	/*
	 * public static void main(String[] args) throws InterruptedException {
	 * run(1, 0, -900, 1); // mit Spielerinformation(en) run(2, 10, 10, 1); //
	 * mit Balkeninformation }
	 */

	private int getPrefix(double d) {
		if (d < 0)
			return -1;
		return 1;

	}

}
